import json
import random

from channels.generic.websocket import WebsocketConsumer
from app.service import service_select
from channels.layers import get_channel_layer

conn_map = {}


class UserSpecificConsumer(WebsocketConsumer):
    online_users = {}
    online_number = 0

    def websocket_connect(self, message):
        self.user_id = self.scope['url_route']['kwargs']['user_id']
        self.username = self.scope['url_route']['kwargs']['username']

        # 将用户添加到在线用户列表
        self.online_users[self.user_id] = self
        self.online_number += 1

        # 查询好友列表
        sql = """
                SELECT
                    t1.user_chat_friend_id,
                    t1.user_id,
                    t1.friend_user_id,
                    t1.friend_user_name,
                    t1.create_time,
                    t1.update_time,
                    t2.username,
                    t2.nickname,
                    t2.avatar
                FROM
                    user_chat_friend t1
                LEFT JOIN `user` t2 ON t1.friend_user_id = t2.user_id
                WHERE
                    t1.user_id = %s
            """ % (self.user_id)
        result = service_select("user_chat_friend").run(sql)

        # 接受连接
        self.accept()

        # 构建消息并发送给好友
        message = {"message_type": 1, "user_id": self.user_id, "username": self.username}
        if result:
            user_list = [{"user_id": row["friend_user_id"]} for row in result]
            self.send_message_to_all(user_list, message)

        # 发送在线用户列表
        map_self = {"message_type": 3, "onlineUsers": list(self.online_users.keys())}
        self.send_message_to(self.user_id, map_self)

    def websocket_disconnect(self, close_code):
        # 从在线用户列表中移除
        if self.user_id in self.online_users:
            del self.online_users[self.user_id]
            self.online_number -= 1

        # 查询好友列表
        sql = """
                SELECT
                    t1.user_chat_friend_id,
                    t1.user_id,
                    t1.friend_user_id,
                    t1.friend_user_name,
                    t1.create_time,
                    t1.update_time,
                    t2.username,
                    t2.nickname,
                    t2.avatar
                FROM
                    user_chat_friend t1
                LEFT JOIN `user` t2 ON t1.friend_user_id = t2.user_id
                WHERE
                    t1.user_id = %s
            """ % (self.user_id)
        result = service_select("user_chat_friend").run(sql)

        # 构建消息并发送给好友
        message = {
            "message_type": 2,
            "onlineUsers": list(self.online_users.keys()),
            "user_id": self.user_id,
            "username": self.username
        }
        if result:
            user_list = [{"user_id": row["friend_user_id"]} for row in result]
            self.send_message_to_all(user_list, message)
        print("WebSocket closed")

    def websocket_receive(self, event):
        text_data = event["text"]
        body = json.loads(text_data)

        if body.get("to", {}).get("type") == "read":
            if body.get("to", {}).get("read_list"):
                sql = "DELETE FROM user_chat_read WHERE user_chat_read_id IN ("
                for read_id in body["to"]["read_list"]:
                    sql = sql + "'" + read_id + "'" + ","
                sql = sql[:-1]
                sql = sql + ")"
                service_select("user_chat_friend").run(sql)

        elif body.get("to", {}).get("type") == "group":
            sql = """SELECT user_id FROM user_chat_group WHERE group_id = %s AND user_id <> %s""" % (
                body["to"]["group_id"], body["user_id"])
            result = service_select("user_chat_group").run(sql)

            if result:
                uuid_list = [self.generate_uuid() for _ in range(len(result))]
                message = {"message_type": 4, "text_message": json.dumps(body["message"], ensure_ascii=False),
                           "from_username": body["username"], "to_user_id": "group"}

                insert_message = {"message_type": 4, "text_message": json.dumps(json.dumps(body["message"], ensure_ascii=False), ensure_ascii=False),
                           "from_username": body["username"], "to_user_id": "group"}

                read_sql = "INSERT INTO user_chat_read (user_chat_read_id, user_id, send_user_id, group_id, `type`, message) VALUES "
                values = []
                for i, row in enumerate(result):
                    insert_value = json.dumps(insert_message, ensure_ascii=False).replace('"\\"', '\\"').replace('\\""', '\\"')
                    values.append(
                        f"('{uuid_list[i]}', {row['user_id']}, {body['user_id']}, {body['to']['group_id']}, 2, '{insert_value}')")
                read_sql += ",".join(values)

                service_select("user_chat_friend").run(read_sql)

                for i, row in enumerate(result):
                    message["user_chat_read_id"] = uuid_list[i]
                    self.send_message_to(row["user_id"], message)

        else:
            uuid = self.generate_uuid()
            send_message = {
                "message_type": 4,
                "text_message": json.dumps(body["message"], ensure_ascii=False),
                "from_username": body["username"],
                "to_user_id": body["to"]["user_id"],
                "user_chat_read_id": uuid
            }

            insert_message = {
                "message_type": 4,
                "text_message": json.dumps(json.dumps(body["message"], ensure_ascii=False), ensure_ascii=False),
                "from_username": body["username"],
                "to_user_id": body["to"]["user_id"],
                "user_chat_read_id": uuid
            }

            service_select("user_chat_read").Add(
                {"user_chat_read_id": uuid, "user_id": str(body["to"]["user_id"]), "send_user_id": str(body["user_id"]),
                 "type": 1, "message": json.dumps(insert_message, ensure_ascii=False).replace('"\\"', '\\"').replace('\\""', '\\"')})

            self.send_message_to(body["to"]["user_id"], send_message)

    @staticmethod
    def generate_uuid():
        return ''.join(random.choices("0123456789abcdef", k=32))

    @classmethod
    def send_message_to(cls, user_id, message):
        """
        向指定用户发送消息（外部可调用）
        """
        if str(user_id) in cls.online_users:
            try:
                cls.online_users[str(user_id)].send(json.dumps(message, ensure_ascii=False))
            except Exception as e:
                print(f"Error sending message to user {user_id}: {e}")
        else:
            print(f"User {user_id} is not online, message cannot be sent.")

    @classmethod
    def send_message_to_all(cls, user_list, message):
        """
        向用户列表中的所有用户发送消息（外部可调用）
        """
        for user in user_list:
            cls.send_message_to(user["user_id"], message)
